home *** CD-ROM | disk | FTP | other *** search
- /* Internet TTY "link" (keyboard chat) server
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include "global.h"
- #include "commands.h"
- #ifndef MSDOS
- #include <time.h>
- #endif
- #include "mbuf.h"
- #include "socket.h"
- #include "telnet.h"
- #include "mailbox.h"
- #include "x.h"
- #include "stats.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: ttylink.c,v 1.21 1997/07/31 00:44:20 root Exp root $";
- #endif
-
- #ifdef ALLSERV
- static int Sttylink = -1; /* Protoype socket for service */
- int Attended = TRUE; /* default to attended mode */
- static int Screening; /* default to non-screened mode */
-
- static char Tnbanner[] = "Welcome to TTY-Link at %s - The system is %s.\n";
- static char defaultDeny[] = "Sorry, but the SYSOP is unable to join you at this time...";
- extern const char SysopBusy[];
- extern char *Motd;
-
- int ScreenedCall;
- char *ScreenedCaller;
- static int SCREENretries = 60;
- #ifdef SOUNDS
- static char *SCREENsound;
- static char *CONNECTsound;
- #endif
- static char *DENYstr;
-
- int CHAToneshotBypass = 0;
-
-
-
- int
- ttylstart(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- struct sockaddr_in lsocket;
- int s, type, i;
- char addr[MAXSOCKSIZE];
- int len = MAXSOCKSIZE;
- time_t nowtime;
-
- if (Sttylink != -1)
- return 0;
-
- ksignal (Curproc, 0); /* Don't keep the parser waiting */
- chname (Curproc, "TTYlink listener");
- server_disconnect_io ();
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- if (argc < 2)
- lsocket.sin_port = IPPORT_TTYLINK;
- else
- lsocket.sin_port = (int16) atoi (argv[1]);
-
- Sttylink = socket (AF_INET, SOCK_STREAM, 0);
- (void) bind (Sttylink, (char *)&lsocket, sizeof (lsocket));
- (void) listen (Sttylink, 1);
- for ( ; ; ) {
- if ((s = accept (Sttylink, NULLCHAR, (int *)NULL)) == -1)
- break; /* Service is shutting down */
-
- if (!Attended) {
- busy: usprintf (s, SysopBusy);
- close: (void) shutdown (s, 1);
- close_s (s);
- } else {
- if (Screening && !CHAToneshotBypass) {
- while (ScreenedCall == -1)
- kpause (1000);
- usprintf (s, "Paging SYSOP, stand by....\n");
- usflush (s);
- ScreenedCall = -1;
- #ifdef SOUNDS
- if (SCREENsound)
- (void) playsound (SCREENsound);
- else
- #endif
- tcmdprintf ("\007");
- (void) time (&nowtime); /* current time */
- if (getpeername (s, addr, &len) != -1)
- ScreenedCaller = strdup (psocket (addr));
- else
- ScreenedCaller = strdup ("unknown");
- #ifdef XSERVER
- xnotify (X_SCREEN);
- #endif
- tcmdprintf ("*** Incoming chat request from %s on %s\n",
- ScreenedCaller, ctime (&nowtime));
- for (i = 0; i < SCREENretries; i++) {
- if (ScreenedCall != -1)
- break;
- kpause (1000);
- }
- free (ScreenedCaller);
- ScreenedCaller = NULLCHAR;
- #ifdef XSERVER
- xnotify (X_SCREEN);
- #endif
- switch (ScreenedCall) {
- case 0: /* denied */
- usprintf (s, "%s\n", (DENYstr && *DENYstr) ? DENYstr : defaultDeny);
- goto close;
- case -1: /* unanswered */
- ScreenedCall = 0;
- #ifdef XSERVER
- xnotify (X_SCREEN);
- #endif
- goto busy;
- case 1: /* accepted */
- usprintf (s, "Call accepted by SYSOP!\n");
- break;
- default:
- break;
- }
- }
- CHAToneshotBypass = 0;
- type = TELNET;
- if (newproc ("chat", 2048, ttylhandle, s, (void *)&type, NULL, 0) == NULLPROC) {
- (void) shutdown (s, 1);
- close_s (s);
- }
- }
- }
- return 0;
- }
-
-
- /* This function handles all incoming "chat" sessions, be they TCP,
- * NET/ROM or AX.25
- */
- void
- ttylhandle (s, t, p)
- int s;
- void *t;
- void *p OPTIONAL;
- {
- int type, theindex;
- struct session *sp;
- char addr[MAXSOCKSIZE];
- int len = MAXSOCKSIZE;
- struct telnet tn;
- time_t nowtime;
- int validaddr;
-
- type = * (int *)t;
- (void) sockmode (s, SOCK_ASCII);
- (void) sockowner (s, Curproc); /* We own it now */
- log (s, "open %s", Sestypes[type]);
-
- /* Allocate a session descriptor */
- if ((sp = newsession (NULLCHAR, type, 1)) == NULLSESSION) {
- tputs (TooManySessions);
- close_s (s);
- return;
- }
- #ifdef STATS_USE
- STATS_adduse (1);
- MiscUsers++;
- #endif
- theindex = sp - Sessions;
-
- /* Initialize a Telnet protocol descriptor */
- memset ((char *)&tn, 0, sizeof (tn));
- tn.session = sp; /* Upward pointer */
- sp->cb.telnet = &tn; /* Downward pointer */
- sp->s = s;
- sp->proc = Curproc;
-
- (void) time (&nowtime); /* current time */
-
- validaddr = getpeername (s, addr, &len);
- #ifdef SOUNDS
- if (CONNECTsound)
- (void) playsound (CONNECTsound);
- else
- #endif
- tputc ('\007');
-
- tprintf ("Incoming %s session %u from %s on %s",
- Sestypes[type], theindex, (validaddr != -1) ? psocket(addr) : "unknown host", ctime (&nowtime));
-
- usprintf (s, Tnbanner, Hostname, Attended ? "attended" : "unattended");
- if (Motd != NULLCHAR)
- usprintf (s, "%s", Motd);
-
- tnrecv (&tn);
- #ifdef STATS_USE
- MiscUsers--;
- #endif
- }
-
-
- /* Shut down Ttylink server */
- int
- ttyl0 (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- return (deleteserver (&Sttylink));
- }
-
-
- static int doretries (int argc,char *argv[],void *p);
- static int doattended (int argc,char *argv[],void *p);
- static int doscreening (int argc,char *argv[],void *p);
- static int doaccept (int argc,char *argv[],void *p);
- static int dodeny (int argc,char *argv[],void *p);
- static int dodenystr (int argc,char *argv[],void *p);
- #ifdef SOUNDS
- static int doscreensound (int argc,char *argv[],void *p);
- static int doconnectsound (int argc,char *argv[],void *p);
- #endif
-
- /* chat subcommand table */
- static struct cmds CHATtab[] = {
- { "accept", doaccept, 0, 0, NULLCHAR },
- { "attended", doattended, 0, 0, NULLCHAR },
- #ifdef SOUNDS
- { "connectsound", doconnectsound, 0, 0, NULLCHAR },
- #endif
- { "deny", dodeny, 0, 0, NULLCHAR },
- { "denystr", dodenystr, 0, 0, NULLCHAR },
- { "retries", doretries, 0, 0, NULLCHAR },
- { "screening", doscreening, 0, 0, NULLCHAR },
- #ifdef SOUNDS
- { "screensound", doscreensound, 0, 0, NULLCHAR },
- #endif
- #if defined(MAILBOX) && defined(GATECMDS)
- { "with", dombchat, 0, 2, "chat with <bbsuser>" },
- #endif
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
- int
- chatcmd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd(CHATtab,argc,argv,p);
- }
-
-
- /* if unattended mode is set - restrict ax25, telnet and maybe other sessions */
- int
- doattended(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setbool(&Attended,"Incoming Chat Attended",argc,argv);
- }
-
-
- /* if attended mode is set, do we screen the incoming calls? */
- int
- doscreening(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setbool(&Screening,"Incoming Chat Screening",argc,argv);
- }
-
-
- /* if attended mode is set, do we screen the incoming calls? */
- int
- doretries(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setint(&SCREENretries,"Time for Screened Callers to wait (in secs)",argc,argv);
- }
-
-
- /* to accept the waiting incoming call */
- int
- doaccept(argc,argv,p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- ScreenedCall = 1;
- return 0;
- }
-
-
- /* to deny the waiting incoming call */
- int
- dodeny(argc,argv,p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- ScreenedCall = 0;
- return 0;
- }
-
-
- int
- dodenystr(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if(argc < 2) {
- if (DENYstr)
- tprintf ("%s\n", DENYstr);
- } else {
- if (DENYstr)
- free (DENYstr);
- DENYstr = strdup (argv[1]);
- }
- return 0;
- }
-
-
- #ifdef SOUNDS
- int
- doscreensound(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return (setsoundstr (argc, argv, &SCREENsound));
- }
-
-
- int
- doconnectsound(argc,argv,p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return (setsoundstr (argc, argv, &CONNECTsound));
- }
- #endif /* SOUNDS */
-
- #endif /*ALLSERV*/
-